package liuwanghui.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import liuwanghui.common.Result;
import liuwanghui.constant.OrderStatusConstant;
import liuwanghui.constant.ProductStatusConstant;
import liuwanghui.dto.request.*;
import liuwanghui.dto.response.HotProductDTO;
import liuwanghui.dto.response.LowStockProductDTO;
import liuwanghui.exception.BusinessException;
import liuwanghui.mapper.DealerMapper;
import liuwanghui.pojo.Inventory;
import liuwanghui.pojo.Order;
import liuwanghui.pojo.Product;
import liuwanghui.service.DealerService;
import liuwanghui.vo.InventoryVO;
import liuwanghui.vo.OrderVO;
import liuwanghui.vo.ProductVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class DealerServiceImpl implements DealerService {

    private final DealerMapper dealerMapper;

    @Override
    @Cacheable(value = "dealer:statistics", key = "#timeRange + '-' + #category")
    public Result getStatistics(String timeRange, String startDate, String endDate, 
                              String category, Boolean includeDetails) {
        try {
            Map<String, Object> stats = new HashMap<>();
            
            // 基础统计
            stats.put("totalProducts", dealerMapper.getTotalProducts());
            stats.put("pendingOrders", dealerMapper.getPendingOrders());
            stats.put("monthSales", dealerMapper.getMonthSales());
            
            // 时间范围统计
            LocalDateTime start = getStartTime(timeRange, startDate);
            LocalDateTime end = getEndTime(timeRange, endDate);
            
            BigDecimal salesAmount = dealerMapper.getSalesByDateRange(start, end, category);
            stats.put("salesAmount", salesAmount);
            
            // 详细统计
            if (Boolean.TRUE.equals(includeDetails)) {
                List<Map<String, Object>> categoryStats = dealerMapper.getCategoryStats(start, end);
                List<Map<String, Object>> dailyStats = dealerMapper.getDailyStats(start, end);
                stats.put("categoryStats", categoryStats);
                stats.put("dailyStats", dailyStats);
            }
            
            return Result.success(stats);
        } catch (Exception e) {
            log.error("获取统计数据失败", e);
            throw new BusinessException("获取统计数据失败");
        }
    }

    @Override
    public Result getLowStockProducts(Integer threshold, String category, 
                                    String warehouse, Integer page, Integer pageSize) {
        try {
            PageHelper.startPage(page, pageSize);
            List<LowStockProductDTO> products = dealerMapper.getLowStockProducts(threshold, category, warehouse);
            return Result.success(new PageInfo<>(products));
        } catch (Exception e) {
            log.error("获取库存预警商品失败", e);
            throw new BusinessException("获取库存预警商品失败");
        }
    }

    @Override
    public Result getHotProducts() {
        try {
            List<HotProductDTO> products = dealerMapper.getHotProducts();
            return Result.success(products);
        } catch (Exception e) {
            log.error("获取热销商品失败", e);
            throw new BusinessException("获取热销商品失败");
        }
    }

    @Override
    public Result getProducts(ProductQueryDTO params) {
        try {
            PageHelper.startPage(params.getPage(), params.getPageSize());
            List<ProductVO> products = dealerMapper.findProductsBySearch(params);
            return Result.success(new PageInfo<>(products));
        } catch (Exception e) {
            log.error("获取商品列表失败", e);
            throw new BusinessException("获取商品列表失败");
        }
    }

    @Override
    @Transactional
    @CacheEvict(value = "dealer:product", key = "#productId")
    public Result updateProductStatus(Long productId, ProductStatusDTO dto) {
        try {
            Product product = dealerMapper.findProductById(productId);
            if (product == null) {
                throw new BusinessException("商品不存在");
            }

            // 检查状态是否允许变更
            if (dto.getStatus().equals(product.getStatus())) {
                return Result.success("状态未变更");
            }

            // 更新商品状态
            dealerMapper.updateProductStatus(productId, dto.getStatus());

            // 记录状态变更日志
            ProductStatusLogDTO log = new ProductStatusLogDTO();
            log.setProductId(productId);
            log.setOldStatus(product.getStatus());
            log.setNewStatus(dto.getStatus());
            log.setRemark(dto.getRemark());
            log.setOperator("system"); // TODO: 从上下文获取当前操作人
            dealerMapper.insertProductStatusLog(log);

            return Result.success("状态更新成功");
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("���新商品状态失败", e);
            throw new BusinessException("更新商品状态失败");
        }
    }

    @Override
    @Transactional
    @CacheEvict(value = "dealer:product", key = "#id")
    public Result deleteProduct(Long id) {
        try {
            Product product = dealerMapper.findProductById(id);
            if (product == null) {
                throw new BusinessException("商品不存在");
            }

            // 逻辑删除
            dealerMapper.updateProductStatus(id, ProductStatusConstant.DELETED);

            // 记录状态变更日志
            ProductStatusLogDTO log = new ProductStatusLogDTO();
            log.setProductId(id);
            log.setOldStatus(product.getStatus());
            log.setNewStatus(ProductStatusConstant.DELETED);
            log.setRemark("商品删除");
            log.setOperator("system"); // TODO: 从上下文获取当前操作人
            dealerMapper.insertProductStatusLog(log);

            return Result.success("删除成功");
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除商品失败", e);
            throw new BusinessException("删除商品失败");
        }
    }

    @Override
    @Transactional
    public Result importOrdersToStock(ImportOrdersDTO dto) {
        try {
            // 1. 验证订单状态
            for (Long orderId : dto.getOrderIds()) {
                Order order = dealerMapper.findOrderById(orderId);
                if (order == null || !OrderStatusConstant.COMPLETED.equals(order.getStatus())) {
                    throw new BusinessException("订单" + orderId + "不存在或状态不正确");
                }
            }

            // 2. 更新库存
            for (CheckItemDTO item : dto.getCheckItems()) {
                // 获取当前库存
                Inventory inventory = dealerMapper.findInventoryById(item.getProductId());
                if (inventory == null) {
                    throw new BusinessException("商品" + item.getProductId() + "的库存记录不存在");
                }

                // 记录原库存
                int oldStock = inventory.getCurrentStock();
                
                // 更新库存
                inventory.setCurrentStock(oldStock + item.getActualQuantity());
                dealerMapper.updateInventoryStock(inventory);

                // 记录库存变更日志
                StockLogDTO log = new StockLogDTO();
                log.setInventoryId(inventory.getId());
                log.setOldStock(oldStock);
                log.setNewStock(inventory.getCurrentStock());
                log.setChangeQuantity(item.getActualQuantity());
                log.setOperator(dto.getOperator());
                log.setRemark("订单入库: " + dto.getRemark());
                dealerMapper.insertStockLog(log);
            }

            return Result.success("入库成功");
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("订单入库失败", e);
            throw new BusinessException("订单入库失败");
        }
    }

    @Override
    public Result getInventoryProducts() {
        try {
            List<InventoryVO> products = dealerMapper.getInventoryProducts(null, null, null);
            return Result.success(products);
        } catch (Exception e) {
            log.error("获取库存商品失败", e);
            throw new BusinessException("获取库存商品失败");
        }
    }

    @Override
    public Result getRecentOrders() {
        try {
            List<OrderVO> orders = dealerMapper.getRecentOrders(10);
            return Result.success(orders);
        } catch (Exception e) {
            log.error("获取最近订单失败", e);
            throw new BusinessException("获取最近订单失败");
        }
    }

    @Override
    public Result getCompletedOrders() {
        try {
            List<OrderVO> orders = dealerMapper.getCompletedOrders(10);
            return Result.success(orders);
        } catch (Exception e) {
            log.error("获取已完成订单失败", e);
            throw new BusinessException("获取已完成订单失败");
        }
    }

    // 工具方法：获取开始时间
    private LocalDateTime getStartTime(String timeRange, String startDate) {
        if (startDate != null) {
            return LocalDateTime.parse(startDate);
        }
        
        LocalDateTime now = LocalDateTime.now();
        return switch (timeRange) {
            case "day" -> now.minusDays(1);
            case "week" -> now.minusWeeks(1);
            case "year" -> now.minusYears(1);
            default -> now.minusMonths(1);
        };
    }

    // 工具方法：获取结束时间
    private LocalDateTime getEndTime(String timeRange, String endDate) {
        return endDate != null ? LocalDateTime.parse(endDate) : LocalDateTime.now();
    }
}